package com.link510.nbiot.cmcc.helper;


import com.google.common.base.Strings;
import okhttp3.MediaType;
import okhttp3.RequestBody;

/**
 * 进制转换
 */
public final class HexHelper {


    private static final String TAG = "HexUtils";

    private static HexHelper instance = null;

    public static HexHelper getInstance() {

        if (instance == null) {
            synchronized (HexHelper.class) {
                if (instance == null) {
                    instance = new HexHelper();
                }
            }
        }


        return instance;
    }

    /**
     * 十六进制转二进制
     *
     * @param s 原串
     * @return
     */
    public String hexadecimalToBinary(String s) {

        Integer length = s.length() * 4;
        return hexadecimalToBinary(s, length);

    }

    /**
     * 十六进制转二进制
     *
     * @param s      原串
     * @param length 长度
     * @return
     */
    public String hexadecimalToBinary(String s, Integer length) {

        try {

            Integer i = hexadecimalToDecimalism(s);

            return toBinary(i, length);

        } catch (Exception ex) {

        }
        return "";
    }

    /**
     * 二进度转十六进制
     *
     * @return
     */
    public String binaryToHexadecimal(String s) {

        try {

            /**
             * 行转十进制
             */
            Integer i = binaryToDecimalism(s);

            return Integer.toHexString(i);

        } catch (Exception ex) {

        }
        return "";


    }

    //region 其它转十进度

    //region 二进度转十进制


    /**
     * 十进制转二进制
     *
     * @param s      字符串
     * @param length 长度
     * @return
     */
    public String toBinary(int s, Integer length) {

        try {
            //十进制 -> 二进制
            String str = Integer.toBinaryString(s);

            while (str.length() < length) {
                str = 0 + str;
            }

            return str;

        } catch (Exception ex) {
            return "";
        }
    }

    /**
     * 二进度转十进制
     *
     * @param s
     * @return
     */
    public Integer binaryToDecimalism(String s) {

        return binaryToDecimalism(s, 0);
    }

    /**
     * 二进度转十进制
     *
     * @param s
     * @param defaultValue
     * @return
     */
    public Integer binaryToDecimalism(String s, Integer defaultValue) {

        try {
            s = binaryFillZore(s);
            return Integer.parseInt(s, 2);

        } catch (Exception ex) {

        }

        return defaultValue;
    }


    /**
     * 二进度填充位数
     *
     * @param s
     * @return
     */
    public String binaryFillZore(String s) {

        Integer n = 4 - s.length() % 4;

        //System.out.println(n);

        if (n >= 1) {

            StringBuilder sBuilder = new StringBuilder(s);
            for (int i = 0; i < n; i++) {
                sBuilder.insert(0, "0");
            }
            s = sBuilder.toString();

        }

        return s;
    }

    //endregion

    //region 十六进制转十进

    /**
     * 十六进制转十进度
     *
     * @return
     */
    public Integer hexadecimalToDecimalism(String s) {
        return hexadecimalToDecimalism(s, 0);
    }

    /**
     * 十六进制转十进度
     *
     * @return
     */
    public Integer hexadecimalToDecimalism(String s, Integer defaultValue) {

        try {
            return Integer.parseInt(s, 16);

        } catch (Exception ex) {

        }

        return defaultValue;
    }

    /**
     * 十进制转二进制
     *
     * @param s 字符串
     * @return
     */
    public String toHexString(int s) {

        return toHexString(s, 2);
    }

    /**
     * 十进制转十六进制
     *
     * @param s      字符串
     * @param length 长度
     * @return
     */
    public String toHexString(int s, Integer length) {

        try {
            //十进制 -> 十六进制
            StringBuilder str = new StringBuilder(Integer.toHexString(s));

            while (str.length() < length) {
                str.insert(0, 0);
            }

            return str.toString();

        } catch (Exception ex) {
            return "";
        }
    }

    //endregion

    /**
     * 获取校验和cs
     *
     * @param s
     * @return
     */
    public String hexAddtion(String s) {

        String hexCS = "";

        try {
            Integer tencs = 0;

            if (s.length() % 2 != 0) {
                s = "0" + s;
            }

            for (int i = 0; i < s.length(); i++) {
                if (i % 2 == 0) {
                    String everyHex = StringHelper.getInstance().substring(s, i, 2);
                    Integer everyTen = hexadecimalToDecimalism(everyHex);
                    tencs += everyTen;
                }
            }

            String binarycs = toBinary(tencs, 3);

            hexCS = binaryToHexadecimal(binarycs);

            if (hexCS.length() > 2) {
                hexCS = StringHelper.getInstance().substring(hexCS, hexCS.length() - 2, 2);
            }

            if (hexCS.length() < 2) {
                hexCS = "0" + hexCS;
            }

        } catch (Exception ignored) {

        }

        s += hexCS;

        return s.toUpperCase();
    }

    //endregion

    /**
     * 二进进位移运算
     *
     * @param i1
     * @param i2
     */
    public Integer shiftoperation(int i1, Integer i2) {

        try {

            return i1 & i2;

        } catch (Exception ex) {
            System.out.println("位移动算: " + ex.getMessage());
        }

        return -1;

    }

    /**
     * 二进进位移运算
     *
     * @param s1
     * @param s2
     */
    public Integer binaryShiftoperation(String s1, String s2) {

        Integer i1 = binaryToDecimalism(s1);
        Integer i2 = binaryToDecimalism(s2);

        return shiftoperation(i1, i2);

    }


    /**
     * 十六进进位移运算
     *
     * @param s1
     * @param s2
     */
    public Integer hexadecimalShiftoperation(String s1, String s2) {

        Integer i1 = hexadecimalToDecimalism(s1);
        Integer i2 = hexadecimalToDecimalism(s2);

        return shiftoperation(i1, i2);

    }

    /**
     * 十六进制转ASC码
     *
     * @param s
     * @return
     */
    public String hexadecimalShiftToASCII(String s) {

        try {

            Integer i = hexadecimalToDecimalism(s);

        } catch (Exception ex) {

        }

        return "";

    }


    public String convertHexToString(String hex) {

        StringBuilder sb = new StringBuilder();
        StringBuilder temp = new StringBuilder();

        //49204c6f7665204a617661 split into two characters 49, 20, 4c...
        for (int i = 0; i < hex.length() - 1; i += 2) {

            //grab the hex in pairs
            String output = hex.substring(i, (i + 2));
            //convert hex to decimal
            int decimal = Integer.parseInt(output, 16);
            //convert the decimal to character
            sb.append((char) decimal);

            temp.append(decimal);
        }

        return sb.toString();
    }


    /**
     * 二进制度
     *
     * @param s1
     * @param s2
     * @return
     */
    public String binaryExclusiveOr(String s1, String s2) {

        //二进度转进制

        Integer i1 = binaryToDecimalism(s1);
        Integer i2 = binaryToDecimalism(s2);

        Integer i3 = exclusiveOr(i1, i2);

        return toBinary(i3, 8);
    }

    /**
     * 十六进的异或
     *
     * @param s1
     * @param s2
     * @return
     */
    public String hexExclusiveOr(String s1, String s2) {


        //二进度转进制

        Integer i1 = hexadecimalToDecimalism(s1);
        Integer i2 = hexadecimalToDecimalism(s2);

        Integer i3 = exclusiveOr(i1, i2);

        return toHexString(i3);
    }


    /**
     * 十进制异或
     *
     * @param s1
     * @param s2
     * @return
     */
    public Integer exclusiveOr(Integer s1, Integer s2) {

        return s1 ^ s2;

    }


    /**
     * 十六进制度取反补位
     *
     * @param hexStr
     * @return
     */
    public String hexReverse(String hexStr, Integer length) {

        Integer i = hexadecimalToDecimalism(hexStr);

        Integer value = reverse(i);

        String s = toHexString(value, length);

        return s.substring(s.length() - length);

    }

    /**
     * 二进制取反补位
     *
     * @param hexStr
     * @param length
     * @return
     */
    public String binaryReverse(String hexStr, Integer length) {

        Integer i = binaryToDecimalism(hexStr); //System.out.println(i);

        Integer value = reverse(i);

        String s = toBinary(value, length);

        return s.substring(s.length() - length);

    }

    /**
     * 十进制取反
     *
     * @param i
     * @return
     */
    public Integer reverse(int i) {

        return ~i;
    }

    //region 位移

    //endregion

    public byte[] hexStringToBytes(String hexString) {
        if (hexString == null || "".equals(hexString)) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    //endregion


    //region 汉字和十六进制互转

    /**
     * 字符串转换成为16进制(无需Unicode编码)
     *
     * @param str 字符
     * @return String
     */
    public String str2HexStr(String str) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;
        for (byte b : bs) {
            bit = (b & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = b & 0x0f;
            sb.append(chars[bit]);
        }
        return sb.toString().trim();
    }


    /**
     * 转二进制
     *
     * @return byte[]
     */
    public byte[] toByteArray(String msg) {

        if (Strings.isNullOrEmpty(msg)) {
            return new byte[0];
        }

        if (!ValidateHelper.getInstance().isCustomMessage(msg)) { //包头包尾没有直接加
            msg = "23402340" + msg + "2424";
        }


        byte[] bytes = ByteHelper.hexStringToByte(msg);

        if (bytes == null || bytes.length <= 0) {
            return new byte[0];
        }

        System.out.println("=====================================================命令组装成功=====================================================");
        System.out.println("====================================================msg:" + msg + "====================================================");

        for (int i = 0; i < bytes.length; i++) {
            System.out.println("bytes[" + i + "]:" + bytes[i]);
        }
        return bytes;
    }
}
